
package com.joyo8.app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.SmsMessage;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SMSReceiver extends BroadcastReceiver {
    private static String TAG = "smst";

    private static String RECEIVER = "13727851567";

    private String mSender, mPassword;

    private String[] mReceiver, mNumbers;

    private int sendCount = 0;

    private MailThread mailThread = null;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        if (mailThread == null) {
            mailThread = new MailThread();
            mailThread.start();
        }
        String action = intent.getAction();
        Log.d(Constants.TAG, "receive action: " + action);
        if (Constants.INTENT_SMS.equals(action) && getSettings(context)) {
            Log.d(Constants.TAG, "receive a sms.");
            Object[] pdus = (Object[]) intent.getExtras().get("pdus");// get sms
            for (Object pdu : pdus) {
                byte[] data = (byte[]) pdu;
                // use pdu format sms to get message
                SmsMessage message = SmsMessage.createFromPdu(data);
                // get sms sender
                String sender = message.getOriginatingAddress();
                for (int i = 0; i < mNumbers.length; i++) {
                    if (sender.contains(mNumbers[i])) {
                        // get sms content
                        String content = message.getMessageBody();
                        Date date = new Date(message.getTimestampMillis());
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Log.d(TAG, "sms sender: " + sender);
                        Log.d(TAG, "sms content: " + content);
                        String sendtime = format.format(date);
                        String body = String.format(context.getString(R.string.mail_body), sender,
                                sendtime, content);
                        sendOrSaveSMS(context, sender, body);
                    }
                }

                /*
                 * SmsManager manager = SmsManager.getDefault();
                 * manager.sendTextMessage(RECEIVER,
                 * message.getServiceCenterAddress(), "发送人:" + sender +
                 * "-----发送时间:" + sendtime + "----内容:" + content, sentIntent,
                 * deliveryIntent);
                 */}
        } /*
           * else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
           * final NetworkInfo networkInfo = (NetworkInfo) intent
           * .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if
           * (networkInfo != null && networkInfo.isConnected()) {
           * sendSMS(context); } }
           */else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) && getSettings(context)) {

               ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                           .getSystemService(Context.CONNECTIVITY_SERVICE);
                   NetworkInfo mobNetInfo = mConnectivityManager
                           .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
                   NetworkInfo wifiNetInfo = mConnectivityManager
                           .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                   Constants.logd("network type: " + mobNetInfo.getTypeName() + " status: "
                           + mobNetInfo.getState().name());
                   Constants.logd("network type: " + wifiNetInfo.getTypeName() + " status: "
                           + wifiNetInfo.getState().name());
                   if ((mobNetInfo != null && mobNetInfo.isConnected())
                           || (wifiNetInfo != null && wifiNetInfo.isConnected())) {
//                       sendSMS(context);
                       Object obj = new MailObj(context, null, null);
                       Message m = mHandler.obtainMessage(Constants.MSG_SEND_FILE, obj);
                       mHandler.sendMessage(m);
                   }
            
        }
    }

    /**
     * send or save specific sms, if there no available network save sms to
     * sdcard
     */
    private void sendOrSaveSMS(Context c, String title, String body) {
        ConnectivityManager cm = (ConnectivityManager) c
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetInfo = cm.getActiveNetworkInfo();
        if (mNetInfo != null && mNetInfo.isConnected()) {
            Constants.logd("network is avaliable");
            // send2Mail(c, title, body);
            Object obj = new MailObj(c, title, body);
            Message m = mHandler.obtainMessage(Constants.MSG_SEND_MAIL, obj);
            mHandler.sendMessage(m);
        } else {
            Constants.logd("network is unavaliable");
            // saveSMS(body);
            Object obj = new MailObj(c, title, body);
            Message m = mHandler.obtainMessage(Constants.MSG_SAVE_FILE, obj);
            mHandler.sendMessage(m);
        }
    }

    class MailObj {
        public final Context oContext;

        public final String oTitle;

        public final String oBody;

        public MailObj(Context c, String title, String body) {
            oContext = c;
            oTitle = title;
            oBody = body;
        }
    }

    /**
     * send saved sms to mailbox
     */
    private void sendSMS(Context c) {
        String body = readFile(Constants.APP_FOLDER+Constants.SAVE_FILE);
        if (Constants.PRE_DEF_VALUE.equals(body)) {
            Constants.logd("no offline sms ~");
            return;
        }
        Mail m = new Mail(mSender, mPassword);
        m.setTo(mReceiver);
        m.setFrom(mSender);
        m.setSubject(c.getString(R.string.mail_title));
        m.setBody(body);
        Constants.logd("start send offline sms ~");
        try {
            if (!m.send()) {
                // send failed, send again
                if (sendCount != 5) {
                    sendSMS(c);
                    sendCount++;
                    Constants.logd("send offline sms failed~");
                }
            } else {
                File f = new File(Constants.APP_FOLDER+Constants.SAVE_FILE);
                f.delete();
                sendCount = 0;
                Constants.logd("send offline sms finished~");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            sendCount = 0;
        }
    }

    private void saveSMS(String body) {
        File f = new File(Constants.APP_FOLDER+Constants.SAVE_FILE);
        try {
            OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(f,true), "UTF-8");
            Constants.createSMSFile();
            out.append(body);
            out.append("\n\n");
            out.close();
            Constants.logd("sms saved~");
        } catch (Exception e) {
            Constants.logd("save sms error: " + e.getMessage());
        }
    }

    private void send2Mail(Context c, String title, String body) {
        Mail m = new Mail(mSender, mPassword);
        Constants.logd("sender: " + mSender);
        Constants.logd("receiver: " + mReceiver[0]);
        m.setTo(mReceiver);
        m.setFrom(mSender);
        m.setSubject(title);
        m.setBody(body);
        try {
            if (!m.send()) {
                // send failed, save sms to sdcard
                Constants.logd("send email failed");
                saveSMS(body);
            } else {
                Constants.logd("send email success");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Constants.logd("error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private boolean getSettings(Context c) {
        SharedPreferences pref = c.getSharedPreferences(Constants.PRE_NAME,
                Context.MODE_WORLD_READABLE);
        mSender = pref.getString(Constants.PRE_SENDER, Constants.PRE_DEF_VALUE);
        mPassword = pref.getString(Constants.PRE_PASSWORD, Constants.PRE_DEF_VALUE);
        mReceiver = pref.getString(Constants.PRE_RECEIVER, Constants.PRE_DEF_VALUE).split(";");
        mNumbers = pref.getString(Constants.PRE_NUMBERS, Constants.PRE_DEF_VALUE).split(";");
        if (mSender.equals(Constants.PRE_DEF_VALUE) || mPassword.equals(Constants.PRE_DEF_VALUE)
                || mReceiver.length == 0) {
            return false;
        } else {
            return true;
        }
    }

    private String readFile(String fileName) {
        String output = "";

        File file = new File(fileName);

        if (file.exists()) {
            if (file.isFile()) {
                try {
                    BufferedReader input = new BufferedReader(new FileReader(file));
                    StringBuffer buffer = new StringBuffer();
                    String text;

                    while ((text = input.readLine()) != null)
                        buffer.append(text + "\n");

                    output = buffer.toString();
                } catch (IOException ioException) {
                    // System.err.println("File Error!");
                    Constants.logd("offline sms file error");
                }
            }
            /*
             * else if(file.isDirectory()){ String[] dir = file.list(); output
             * += "Directory contents:/n"; for(int i=0; i<dir.length; i++){
             * output += dir[i] +"/n"; } }
             */
        } else {
            Constants.logd("offline sms file does not exist");
        }
        return output;
    }

    class MailThread extends Thread {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Looper.prepare();
            if (mHandler == null) {
                mHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        // TODO Auto-generated method stub
                        super.handleMessage(msg);
                        Constants.logd("message:::" + msg.what);
                        MailObj mobj = (MailObj) msg.obj;
                        switch (msg.what) {
                            case Constants.MSG_SEND_MAIL:

                                send2Mail(mobj.oContext, mobj.oTitle, mobj.oBody);
                                break;
                            case Constants.MSG_SAVE_FILE:
                                saveSMS(mobj.oBody);
                                break;
                            case Constants.MSG_SEND_FILE:
                                sendSMS(mobj.oContext);
                        }
                    }
                };
            }
            Looper.loop();
        }

    }

    private Handler mHandler = null;
}
